package com.atguigu.day02;


//线程间通信



import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

// 有一个初始值为零的变量，现有两个线程对该变量操作，
// * 实现一个线程对变量加1，实现一个线程对变量减1,交替来10轮
// 判断  干活   通知
//要使用while来避免虚假唤醒
class Resource{
    //初始值为0
    private int num = 0;
    //变量加一
//    public synchronized void increment() throws InterruptedException {
//        //判断
//        while(num!=0){
//            //这时不符合条件，要先等待
//            this.wait();
//        }
//        //干活
//        System.out.println(Thread.currentThread().getName()+"进行+，得到"+(++num));
//        //通知（唤醒其他进程）
//        this.notifyAll();
//    }
    //第二版
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
        public  void increment() throws InterruptedException {
            lock.lock();
            try {
                //判断
                while(num!=0){
                    //这时不符合条件，要先等待
                    condition.await();
                }
                //干活
                System.out.println(Thread.currentThread().getName()+"进行+，得到"+(++num));
                //通知（唤醒其他进程）
                condition.signalAll();
            }finally {
                lock.unlock();
            }


    }

//    public synchronized void decrement() throws InterruptedException {
//        while(num==0){
//            //不符合条件，等待
//           this.wait();
//        }
//        //干活
//        System.out.println(Thread.currentThread().getName()+"进行-，得到"+(--num));
//        //通知（唤醒其他进程）
//        this.notifyAll();
//    }
public  void decrement() throws InterruptedException {
    lock.lock();
    try {
        //判断
        while (num==0){
            //这时不符合条件，要先等待
            condition.await();
        }
        //干活
        System.out.println(Thread.currentThread().getName()+"进行+，得到"+(--num));
        //通知（唤醒其他进程）
        condition.signalAll();
    }finally{
        lock.unlock();
    }

}

}
public class Thread_correspondence {
    public static void main(String[] args) {
        Resource resource = new Resource();
         new Thread(() -> {
             for (int i = 0; i < 10; i++) {
                 try {
                     resource.increment();
                 } catch (InterruptedException e) {
                     throw new RuntimeException(e);
                 }
             }
                 }, "A").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {

                try {
                    resource.decrement();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }, "B").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    resource.increment();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }, "C").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {

                try {
                    resource.decrement();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }, "D").start();
    }
}
